package me.sdevil507.org.controller;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.exceptions.OrgNameEnExistedException;
import me.sdevil507.biz.common.exceptions.OrgNameZhExistedException;
import me.sdevil507.biz.common.sysdict.po.SysDict;
import me.sdevil507.biz.common.sysdict.service.SysdictService;
import me.sdevil507.org.dto.OrgMergeParamsDto;
import me.sdevil507.org.dto.OrgParamsDto;
import me.sdevil507.org.dto.OrgResultDto;
import me.sdevil507.org.dto.OrgUserRelResultDto;
import me.sdevil507.org.mapper.OrgMapper;
import me.sdevil507.org.mapper.OrgUserRelMapper;
import me.sdevil507.org.po.OrgPo;
import me.sdevil507.org.po.OrgUserRelPo;
import me.sdevil507.org.service.OrgService;
import me.sdevil507.supports.result.ApiResultDTO;
import me.sdevil507.supports.result.ApiResultGenerator;
import me.sdevil507.supports.shiro.helper.OrgAccountHelper;
import me.sdevil507.supports.shiro.realm.OrgUsernamePasswordRealm;
import me.sdevil507.supports.status.ApiStatusCode;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 机构[OrgController]
 *
 * @author sdevil507
 * created on 2020-07-13 13:40:20
 */
@RestController
@RequestMapping("/api/org")
@Slf4j
public class OrgController {

    @Autowired
    private OrgUsernamePasswordRealm orgUsernamePasswordRealm;

    @Autowired
    private OrgService orgService;

    @Autowired
    private OrgUserRelMapper orgUserRelMapper;

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private SysdictService sysdictService;

    /**
     * 根据二级域名前缀获取智库信息
     *
     */
    @RequestMapping(value = "/getOrgInfoByChildrenDomainName", method = RequestMethod.POST)
    public ApiResultDTO getOrgInfoByChildrenDomainName(@RequestBody OrgParamsDto dto) {

        OrgPo orgPo = orgService.getOrgInfoByPreDomainName(dto.getPreDomainName());

        OrgResultDto orgResultDto = orgMapper.po2dto(orgPo);

        return ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription(), orgResultDto);
    }


    /**
     * 分页获取信息列表
     *
     * @param dto 聚合查询/分页/排序参数
     * @return 分页数据
     */
    @RequiresPermissions("org:info:view")
    @RequestMapping(value = "/readOne", method = RequestMethod.POST)
    public ApiResultDTO readOne(@RequestBody OrgMergeParamsDto dto) {
        if(ObjectUtil.isEmpty(OrgAccountHelper.getOrgId())){
            return ApiResultGenerator.create(ApiStatusCode.ERROR.getCode(), ApiStatusCode.ACCOUNT_NOT_ADMIN_ROLE.getDescription());
        }
        OrgPo orgPo = orgService.readOne(OrgAccountHelper.getOrgId());

        OrgResultDto orgResultDto = orgMapper.po2dto(orgPo);

        //获取研究领域
        String domain = orgPo.getDomain();
        if(!StringUtils.isEmpty(domain)){
            String[] domainArr = domain.split(",");
            String domains = "";
            for (String val : domainArr) {
                List<SysDict> sysDicts = sysdictService.findByTypeKeyAndValue("ResearchDomain", val);
                if (sysDicts.size() > 0) {
                    domains += sysDicts.get(0).getDname() + ",";
                }
            }
            orgResultDto.setDomainsName(domains.length() > 0 ? domains.substring(0, domains.length()-1) : domains);
        }

        return ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription(), orgResultDto);
    }

    /**
     * 更新
     *
     * @param dto 传输类
     * @return 执行反馈
     */
    @RequiresPermissions("org:info:edit")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public ApiResultDTO update(@RequestBody OrgParamsDto dto) {
        try {
            dto.setId(OrgAccountHelper.getOrgId());
            orgService.update(dto);
        } catch (OrgNameZhExistedException e) {
            return ApiResultGenerator.create(ApiStatusCode.ORG_NAME_ZH_EXISTED.getCode(), ApiStatusCode.ORG_NAME_ZH_EXISTED.getDescription());
        } catch (OrgNameEnExistedException e) {

            return ApiResultGenerator.create(ApiStatusCode.ORG_NAME_EN_EXISTED.getCode(), ApiStatusCode.ORG_NAME_EN_EXISTED.getDescription());
        }
        return ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
    }

    /**
     * 切换组织机构
     *
     * @return 反馈
     */
    @PostMapping("/switchOrg")
    public ApiResultDTO switchOrg(@RequestBody OrgParamsDto dto) {
        // 设置切换后的机构id
        OrgAccountHelper.setOrgId(dto.getId());
        // 清楚权限相关缓存
        orgUsernamePasswordRealm.clearCachedAuthorizationInfo(OrgAccountHelper.getUsername());
        return ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
    }

    /**
     * 获取org列表与当前org
     *
     * @return 反馈
     */
    @PostMapping("/readOrgs")
    public ApiResultDTO readOrgs() {
        // 返回当前登录机构与可切换登录机构
        List<OrgUserRelPo> pos = orgService.readOrgsByAccId();
        List<OrgUserRelResultDto> dtos = orgUserRelMapper.pos2dtos(pos);
        // 标记当前登录机构
        for (OrgUserRelResultDto orgUserRelResultDto : dtos) {
            if (OrgAccountHelper.getOrgId().equals(orgUserRelResultDto.getOrg().getId())) {
                orgUserRelResultDto.setCurrent(true);
            }
        }

        //noinspection Convert2Lambda
        dtos.sort(new Comparator<OrgUserRelResultDto>() {
            @Override
            public int compare(OrgUserRelResultDto o1, OrgUserRelResultDto o2) {
                if (o1.isCurrent() ^ o2.isCurrent()) {
                    return o1.isCurrent() ? -1 : 1;
                } else {
                    return 0;
                }
            }
        });
        Map<String, Object> result = new HashMap<>(1);
        result.put("orgUserRels", dtos);
        return ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription(), result);
    }
}